package com.zqc.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

/**
 * 自定义拦截器
 */
@Activate(group = {CommonConstants.CONSUMER})
public class TPMonitorFilter implements Filter {
    public static Map<String, TreeSet<DimTime>> REQUEST_MAP = new HashMap<>();

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        // 开始时间
        long startTime = System.currentTimeMillis();
        // 执行
        Result result = invoker.invoke(invocation);
        // 结束时间
        long endTime = System.currentTimeMillis();
//        System.out.println("耗时为：" + (endTime - startTime) + "毫秒");

        String serviceName = invocation.getServiceName();
        String methodName = invocation.getMethodName();
        String key = serviceName + "." + methodName;

        synchronized (REQUEST_MAP) {
            TreeSet<DimTime> set = REQUEST_MAP.get(key);
            if (set == null) {
                set = new TreeSet<>();
                REQUEST_MAP.put(key, set);
            }
            set.add(new DimTime(startTime, endTime - startTime));
            REQUEST_MAP.put(key, set);
        }

        return result;
    }

    public static class DimTime implements Comparable<DimTime>, Serializable {
        private Long startTime;
        private Long spendTime;

        public DimTime(Long startTime, Long spendTime) {
            this.startTime = startTime;
            this.spendTime = spendTime;
        }

        public Long getSpendTime() {
            return spendTime;
        }

        public Long getStartTime() {
            return startTime;
        }

        @Override
        public int compareTo(DimTime o) {
            if (spendTime < o.spendTime) {
                return -1;
            } else if (spendTime > o.spendTime) {
                return 1;
            }

            return 0;
        }
    }
}
